<?php

namespace iBrand\Shop\Backend\Http\Controllers\Promotion;

use Carbon\Carbon;
use iBrand\Backend\Http\Controllers\Controller;
use iBrand\Component\Goods\Models\Season;
use iBrand\Shop\Core\Models\O2oDiscountRelation;
use iBrand\Store\Backend\Model\ElDiscount;
use iBrand\Store\Backend\Model\ElDiscountCoupon;
use iBrand\Store\Backend\Model\User;
use iBrand\Store\Backend\Repositories\DiscountRepository;
use Illuminate\Http\Request;
use iBrand\Store\Backend\Repositories\CategoryRepository;
use iBrand\Store\Backend\Service\DiscountService;
use DB;
use Validator;
use iBrand\Store\Backend\Repositories\OrderAdjustmentRepository;
use iBrand\Store\Backend\Repositories\DiscountCouponRepository;
use Encore\Admin\Facades\Admin as LaravelAdmin;
use Encore\Admin\Layout\Content;

class CouponController extends Controller
{
    protected $discountRepository;
    protected $categoryRepository;
    protected $discountService;
    protected $orderAdjustmentRepository;
    protected $couponRepository;
    protected $cache;

    public function __construct(DiscountRepository $discountRepository,
                                CategoryRepository $categoryRepository,
                                DiscountService $discountService,
                                OrderAdjustmentRepository $orderAdjustmentRepository,
                                DiscountCouponRepository $discountCouponRepository)
    {
        $this->discountRepository = $discountRepository;
        $this->categoryRepository = $categoryRepository;
        $this->discountService = $discountService;
        $this->orderAdjustmentRepository = $orderAdjustmentRepository;
        $this->couponRepository = $discountCouponRepository;
        $this->cache = cache();
    }

    public function index()
    {
        $condition = $this->getCondition();
        $where = $condition[0];
        $orWhere = $condition[1];

        $coupons = $this->discountRepository->getDiscountList($where, $orWhere);
        if (session('shop_id')) {
            foreach ($coupons as $value) {
                $rule = $value->DiscountContainsShops;
                if ($rule && $rule->RulesValue) {
                    $shop_ids = explode(',', $rule->RulesValue);
                    if (in_array(session('shop_id'), $shop_ids)) {
                        $value->is_see = O2oDiscountRelation::where('shop_id', session('shop_id'))->where('discount_id', $value->id)->value('id');
                    } else {
                        $value->is_see = 0;
                    }
                }
            }
        }

        return LaravelAdmin::content(function (Content $content) use ($coupons) {

            $content->header('优惠券列表');

            $content->breadcrumb(
                ['text' => '门店管理', 'url' => 'shop/list/store', 'no-pjax' => 1],
                ['text' => '促销管理', 'url' => 'shop/discount', 'no-pjax' => 1],
                ['text' => '优惠券列表', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '优惠券管理']
            );


            $content->body(view('shop-backend::promotion.coupon.index', compact('coupons')));
        });

    }

    /**
     * 获取筛选条件
     *
     * @return array
     */
    private function getCondition()
    {
        $where['coupon_based'] = 1;
        $where['channel'] = 'shop';
        $orWhere = [];
        $status = request('status');
        if ($status == 'nstart') {
            $where['status'] = 1;
            $where['starts_at'] = ['>', Carbon::now()];
        }

        if ($status == 'ing') {
            $where['status'] = 1;
            $where['starts_at'] = ['<=', Carbon::now()];
            $where['ends_at'] = ['>', Carbon::now()];
        }

        if ($status == 'end') {
            $where['ends_at'] = ['<', Carbon::now()];

            $orWhere['coupon_based'] = 1;
            $orWhere['status'] = 0;
            $orWhere['channel'] = 'shop';
        }

        if (request('title') != '') {
            $where['title'] = ['like', '%' . request('title') . '%'];
        }

        return [$where, $orWhere];
    }

    public function create()
    {
        $category = $this->categoryRepository->getLevelCategory(0);
        $discount = new ElDiscount();
        $seasons = Season::all();

        return LaravelAdmin::content(function (Content $content) use ($discount, $category,$seasons) {

            $content->header('新建优惠券');

            $content->breadcrumb(
                ['text' => '门店管理', 'url' => 'shop/list/store', 'no-pjax' => 1],
                ['text' => '促销管理', 'url' => 'shop/discount', 'no-pjax' => 1],
                ['text' => '新建优惠券', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '优惠券管理']
            );

            $content->body(view('shop-backend::promotion.coupon.create', compact('discount', 'category','seasons')));
        });

    }

    public function edit($id)
    {
        $discount = ElDiscount::find($id);
        $category = $this->categoryRepository->getLevelCategory(0);
        $seasons = Season::all();

        return LaravelAdmin::content(function (Content $content) use ($discount, $category,$seasons) {

            $content->header('编辑优惠券');

            $content->breadcrumb(
                ['text' => '门店管理', 'url' => 'shop/list/store', 'no-pjax' => 1],
                ['text' => '促销管理', 'url' => 'shop/discount', 'no-pjax' => 1],
                ['text' => '编辑优惠券', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '优惠券管理']
            );

            $content->body(view('shop-backend::promotion.coupon.edit', compact('discount', 'category','seasons')));
        });

    }

    public function store(Request $request)
    {
        $base = $request->input('base');
        $rules = $request->input('rules');
        $action = $request->input('action');
        $point_action = $request->input('point-action');

        if (!$base['usestart_at']) {
            unset($base['usestart_at']);
        }

        $validator = $this->validationForm();
        if ($validator->fails()) {
            $warnings = $validator->messages();
            $show_warning = $warnings->first();

            return $this->ajaxJson(false, [], 404, $show_warning);
        }

        if (!$action['configuration'] AND !$point_action['configuration']) {
            return $this->ajaxJson(false, [], 404, '请至少设置一种优惠动作');
        }

        $contains_product = array_filter($rules, function ($items) {
            return isset($items['type']) && $items['type'] == 'contains_product';
        });
        $contains_category = array_filter($rules, function ($items) {
            return isset($items['type']) && $items['type'] == 'contains_category';
        });
        if (is_array($contains_product) && !empty($contains_product) && is_array($contains_category) && !empty($contains_category)) {
            $contains_product = array_first($contains_product);
            $contains_category = array_first($contains_category);
            $spu = explode(',', $contains_product['value']['spu']);
            $exclude_spu = explode(',', $contains_category['value']['exclude_spu']);
            $merge = array_unique(array_merge($spu, $exclude_spu));
            if (count($merge) != count($spu) + count($exclude_spu)) {

                return $this->ajaxJson(false, [], 500, '规则：排除指定产品与规则：指定产品不能包含同一种商品');
            }
        }

        try {
            DB::beginTransaction();
            if (!$discount = $this->discountService->saveData($base, $action, $rules, 1)) {
                return $this->ajaxJson(false, [], 404, '请至少设置一种规则');
            }

            DB::commit();

            if ($this->cache->has('goods_o2o_discount_cache')) {
                $this->cache->forget('goods_o2o_discount_cache');
            }

            return $this->ajaxJson(true, [], 0, '');
        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception->getMessage());
            \Log::info($exception->getTraceAsString());

            return $this->ajaxJson(false, [], 404, '保存失败');
        }
    }

    protected function validationForm()
    {
        $rules = [
            'base.title' => 'required',
            'base.code' => 'required',
            'base.usage_limit' => 'required | integer',
            'base.starts_at' => 'required | date',
            'base.ends_at' => 'required | date | after:base.starts_at',
        ];
        $message = [
            "required" => ":attribute 不能为空",
            "base.ends_at.after" => ':attribute 不能早于领取开始时间',
            "base.useend_at.after" => ':attribute 不能早于领取截止时间',
            "integer" => ':attribute 必须是整数',
        ];

        $attributes = [
            "base.title" => '优惠券名称',
            "base.code" => '兑换码',
            "base.usage_limit" => '发放总量',
            "base.starts_at" => '开始时间',
            "base.ends_at" => '领取截止时间',
            "base.useend_at" => '使用截止时间',
        ];

        $validator = Validator::make(
            request()->all(),
            $rules,
            $message,
            $attributes
        );

        $validator->sometimes('base.useend_at', 'required|date|after:base.ends_at', function ($input) {
            return $input->base['useend_at'] < $input->base['ends_at'];
        });

        return $validator;
    }

    /**
     * 使用记录
     *
     * @return mixed
     */
    public function useRecord()
    {
        $condition = $this->usedCondition();
        $where = $condition[1];
        $time = $condition[0];
        $id = request('id');

        $coupons = $this->couponRepository->getCouponsHistoryPaginated($where, 20, $time);

        return LaravelAdmin::content(function (Content $content) use ($coupons, $id) {

            $content->header('优惠券使用记录');

            $content->breadcrumb(
                ['text' => '门店管理', 'url' => 'shop/list/store', 'no-pjax' => 1],
                ['text' => '促销管理', 'url' => 'shop/discount', 'no-pjax' => 1],
                ['text' => '优惠券使用记录', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '优惠券管理']

            );

            $content->body(view('shop-backend::promotion.coupon.use_record', compact('coupons', 'id')));
        });

    }

    /**
     * 优惠券使用筛选条件
     *
     * @return array
     */
    private function usedCondition()
    {
        $time = [];
        $where = [];

        $where['user_id'] = ['>', 0];

        if ($id = request('id')) {
            $where['discount_id'] = $id;
        }

        if (!empty(request('value'))) {
            $where[request('field')] = ['like', '%' . request('value') . '%'];
        }

        if (!empty(request('etime')) && !empty(request('stime'))) {
            $where['used_at'] = ['<=', request('etime')];
            $time['used_at'] = ['>=', request('stime')];
        }

        if (!empty(request('etime'))) {
            $time['used_at'] = ['<=', request('etime')];
        }

        if (!empty(request('stime'))) {
            $time['used_at'] = ['>=', request('stime')];
        }

        return [$time, $where];
    }

    /**
     * 领取记录
     *
     * @param $id
     *
     * @return mixed
     */
    public function showCoupons()
    {
        $condition = $this->getCouponCondition();
        $where = $condition[1];
        $time = $condition[0];
        $id = request('id');
        //$coupons = ElDiscountCoupon::where('discount_id', $discount_id)->where('user_id', '>', 0)->orderBy('created_at', 'desc')->paginate(15);
        $coupons = $this->couponRepository->getCouponsPaginated($where, 15, $time);

        //return view('shop-backend::promotion.coupon.show', compact('coupons', 'id'));

        return LaravelAdmin::content(function (Content $content) use ($coupons, $id) {

            $content->header('优惠券明细表');

            $content->breadcrumb(
                ['text' => '门店管理', 'url' => 'shop/list/store', 'no-pjax' => 1],
                ['text' => '促销管理', 'url' => 'shop/discount', 'no-pjax' => 1],
                ['text' => '优惠券明细表', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '优惠券管理']

            );

            $content->body(view('shop-backend::promotion.coupon.show', compact('coupons', 'id')));
        });

    }

    private function getCouponCondition()
    {
        $time = [];
        $where = [];

        if ($id = request('id')) {
            $where['discount_id'] = $id;
        }

        if (!empty(request('value'))) {
            $where['mobile'] = ['like', '%' . request('value') . '%'];
        }

        if (!empty(request('etime')) && !empty(request('stime'))) {
            $where['created_at'] = ['<=', request('etime')];
            $time['created_at'] = ['>=', request('stime')];
        }

        if (!empty(request('etime'))) {
            $time['created_at'] = ['<=', request('etime')];
        }

        if (!empty(request('stime'))) {
            $time['created_at'] = ['>=', request('stime')];
        }

        return [$time, $where];
    }

    /**
     * 发送优惠券页面
     *
     * @return mixed
     */
    public function sendCoupon()
    {
        $id = request('id');
        $coupon = $this->discountRepository->find($id);

        //return view('shop-backend::promotion.coupon.send', compact('coupon', 'id'));

        return LaravelAdmin::content(function (Content $content) use ($coupon, $id) {

            $content->header('发送优惠券');

            $content->breadcrumb(
                ['text' => '门店管理', 'url' => 'shop/list/store', 'no-pjax' => 1],
                ['text' => '促销管理', 'url' => 'shop/discount', 'no-pjax' => 1],
                ['text' => '发送优惠券', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '优惠券管理']

            );


            $content->body(view('shop-backend::promotion.coupon.send', compact('coupon', 'id')));
        });
    }

    /**
     * 筛选用户
     * */
    public function filterUser()
    {
        return view('shop-backend::promotion.coupon.includes.send_user');
    }

    /**
     * 搜索用户
     *
     * @param Request $request
     *
     * @return mixed
     */
    public function getUsers(Request $request)
    {
        $ids = explode(',', $request->input('ids'));
        if (!empty(request('value'))) {
            $user = User::where('name', 'like', '%' . request('value') . '%')
                ->orWhere('mobile', 'like', '%' . request('value') . '%')
                ->orWhere('nick_name', 'like', '%' . request('value') . '%')
                ->paginate(15)->toArray();
        } else {
            $user = User::paginate(15)->toArray();
        }
        $user['ids'] = $ids;

        return $this->ajaxJson(true, $user);
    }

    /**
     * 获取已选择的用户
     *
     * @param Request $request
     *
     * @return mixed
     */
    public function getSelectedUsersByID(Request $request)
    {
        $ids = explode(',', $request->input('ids'));
        $user = User::whereIn('id', $ids)->get();

        return $this->ajaxJson(true, $user);
    }

    /**
     * 给用户发送优惠券
     */
    public function sendAction()
    {
        $user_ids = explode(',', request('user_ids'));
        $discount_id = request('discount_id');
        $discount = ElDiscount::find($discount_id);

        if ($discount->status == 0 OR ($discount->status == 1 AND ($discount->ends_at < Carbon::now() OR $discount->starts_at > Carbon::now()))) {
            return $this->ajaxJson(false, [], 404, '无效的优惠券');
        }

        if (!request('user_ids')) {
            return $this->ajaxJson(false, [], 404, '未选择任何用户');
        }

        if ($discount->usage_limit < count($user_ids)) {
            return $this->ajaxJson(false, [], 404, '该优惠券剩余发行量小于发送的用户总数');
        }

        try {
            DB::beginTransaction();
            foreach ($user_ids as $item) {
                if (!$this->couponRepository->userGetCoupons($item, $discount_id)) {
                    return $this->ajaxJson(false, [], 404, '发送失败');
                }
            }
            DB::commit();

            return $this->ajaxJson(true, ['count' => count($user_ids)], 0, '');
        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception);

            return $this->ajaxJson(false, [], 404, '发送失败');
        }
    }

    /**
     * 生成优惠码modal
     *
     * @return mixed
     */
    public function couponCode()
    {
        $discount_id = request('discount_id');
        $discount = ElDiscount::find($discount_id);

        $countCoupon = ElDiscountCoupon::where('user_id', 0)->where('discount_id', $discount_id)->count();

        //$range = $discount->usage_limit - $countCoupon;
        $range = $discount->usage_limit;
        if ($range >= 1000) {
            $limit = 1000;
        } elseif ($range < 1000 AND $range > 0) {
            $limit = $range;
        } else {
            $limit = 0;
        }

        return view('shop-backend::promotion.coupon.includes.coupon_code_modal', compact('limit', 'discount_id'));

    }

    /**
     * 生成优惠码
     *
     * @return mixed
     */
    public function createCouponCode()
    {
        $number = request('number');
        $discount_id = request('discount_id');
        $discount = ElDiscount::find($discount_id);
        $range = $discount->usage_limit;

        if ($number > 1000 OR $number >= $range) {
            return $this->ajaxJson(false, [], '400', '生成数量超过限制');
        }

        $data = [];
        for ($i = 1; $i <= $number; $i++) {
            $code = $this->buildCode();
            $codeData = ['user_id' => 0, 'code' => $code];
            array_push($data, $codeData);
        }

        $discount->coupons()->createMany($data);
        $discount->decrement('usage_limit', $number);

        return $this->ajaxJson(true);
    }

    private function buildCode()
    {
        $code = build_order_no('CT');
        if (ElDiscountCoupon::where('code', $code)->first()) {
            return $this->buildCode();
        }

        return $code;
    }

    /**
     * 导出生成的优惠码
     *
     * @return mixed
     */
    public function getExportData()
    {
        $page = request('page') ? request('page') : 1;
        $limit = request('limit') ? request('limit') : 50;
        $type = request('type');

        $data = $this->couponRepository->getExportDataPaginate(request('discount_id'), $limit);
        $lastPage = $data['lastPage'];
        $coupons = $data['data'];

        if ($page == 1) {
            session(['export_coupon_code_cache' => generate_export_cache_name('export_coupon_code_cache_')]);
        }
        $cacheName = session('export_coupon_code_cache');

        if ($this->cache->has($cacheName)) {
            $cacheData = $this->cache->get($cacheName);
            $this->cache->put($cacheName, array_merge($cacheData, $coupons), 300);
        } else {
            $this->cache->put($cacheName, $coupons, 300);
        }

        if ($page == $lastPage) {
            $title = ['优惠码'];

            return $this->ajaxJson(true, ['status' => 'done', 'url' => '', 'type' => $type, 'title' => $title, 'cache' => $cacheName, 'prefix' => 'coupon_code_data_']);
        } else {
            $url_bit = route('admin.promotion.coupon.getExportData', array_merge(['page' => $page + 1, 'limit' => $limit], request()->except('page', 'limit')));

            return $this->ajaxJson(true, ['status' => 'goon', 'url' => $url_bit, 'page' => $page, 'totalPage' => $lastPage]);
        }
    }

    /**
     * 导出使用记录
     *
     * @return mixed
     */
    public function getUsedExportData()
    {
        $page = request('page') ? request('page') : 1;
        $limit = request('limit') ? request('limit') : 20;
        $type = request('type');
        $id = request('id');

        $condition = $this->usedCondition();
        $where = $condition[1];
        $time = $condition[0];

        $coupons = $this->couponRepository->getCouponsHistoryPaginated($where, $limit, $time);
        $lastPage = $coupons->lastPage();
        $coupons = $this->discountService->searchAllCouponsHistoryExcel($coupons);

        if ($page == 1) {
            session(['export_coupon_used_cache' => generate_export_cache_name('export_coupon_used_cache_')]);
        }
        $cacheName = session('export_coupon_used_cache');

        if ($this->cache->has($cacheName)) {
            $cacheData = $this->cache->get($cacheName);
            $this->cache->put($cacheName, array_merge($cacheData, $coupons), 300);
        } else {
            $this->cache->put($cacheName, $coupons, 300);
        }

        if ($page == $lastPage) {
            $title = ['使用时间', '优惠券名', '优惠券码', '订单编号', '订单总金额', '订单状态', '用户名', '摘要'];

            return $this->ajaxJson(true, ['status' => 'done', 'url' => '', 'type' => $type, 'title' => $title, 'cache' => $cacheName, 'prefix' => 'coupon_used_data_']);
        } else {
            $url_bit = route('admin.shop.promotion.coupon.getUsedExportData', array_merge(['page' => $page + 1, 'limit' => $limit, 'id' => $id], request()->except('page', 'limit')));

            return $this->ajaxJson(true, ['status' => 'goon', 'url' => $url_bit, 'page' => $page, 'totalPage' => $lastPage]);
        }
    }

    /**
     * 导出领取记录
     *
     * @return mixed
     */
    public function getCouponsExportData()
    {
        $page = request('page') ? request('page') : 1;
        $limit = request('limit') ? request('limit') : 20;
        $type = request('type');
        $id = request('id');

        $condition = $this->getCouponCondition();
        $where = $condition[1];
        $time = $condition[0];

        $coupons = $this->couponRepository->getCouponsPaginated($where, $limit, $time);
        $lastPage = $coupons->lastPage();
        $coupons = $this->discountService->couponsGetDataExcel($coupons);

        if ($page == 1) {
            session(['export_coupon_get_cache' => generate_export_cache_name('export_coupon_get_cache_')]);
        }
        $cacheName = session('export_coupon_get_cache');

        if ($this->cache->has($cacheName)) {
            $cacheData = $this->cache->get($cacheName);
            $this->cache->put($cacheName, array_merge($cacheData, $coupons), 300);
        } else {
            $this->cache->put($cacheName, $coupons, 300);
        }

        if ($page == $lastPage) {
            $title = ['领取时间', '优惠码', '用户', '是否使用', '使用时间'];

            return $this->ajaxJson(true, ['status' => 'done', 'url' => '', 'type' => $type, 'title' => $title, 'cache' => $cacheName, 'prefix' => 'coupon_get_data_']);
        } else {
            $url_bit = route('admin.promotion.coupon.getCouponsExportData', array_merge(['page' => $page + 1, 'limit' => $limit, 'id' => $id], request()->except('page', 'limit')));

            return $this->ajaxJson(true, ['status' => 'goon', 'url' => $url_bit, 'page' => $page, 'totalPage' => $lastPage]);
        }
    }
}